"""
通用浏览器Agent
"""

from typing import Dict, Any, List, Optional
from loguru import logger
from langchain.prompts import ChatPromptTemplate
from langchain.schema import AIMessage, HumanMessage, SystemMessage
from langchain_openai import ChatOpenAI

from ..core.config import settings
from ..tools.tool_executor import tool_executor


class GenericBrowserAgent:
    """
    通用浏览器Agent，负责执行底层浏览器操作
    """
    
    def __init__(self):
        """初始化通用浏览器Agent"""
        # 初始化LLM
        self.llm = ChatOpenAI(
            model=settings.OPENAI_MODEL,
            api_key=settings.OPENAI_API_KEY,
            base_url=settings.OPENAI_BASE_URL,
            temperature=0.1
        )
        
        # 获取工具schema
        self.tools_schema = tool_executor.get_tools_schema()
        
        # 系统提示
        self.system_prompt = """你是一个专业的网页浏览器自动化AI助手，负责执行精确的浏览器操作。
你的任务是将用户的高级指令分解为一系列具体的浏览器操作步骤。

请遵循以下工作流程：
1. 分析用户请求和当前页面状态
2. 设计一个有效的操作序列来完成任务
3. 一步一步地执行这些操作，使用提供的浏览器工具

可用的浏览器操作工具包括：
- navigate_to_url：导航到指定URL
- click_element：点击页面元素
- fill_form：填写表单
- take_screenshot：截取页面截图
- extract_page_content：提取页面内容

当你需要使用工具时，请按照以下格式输出：
```json
{
  "tool_call": {
    "name": "工具名称",
    "arguments": {
      "参数1": "值1",
      "参数2": "值2"
    }
  }
}
```

请确保你的操作是精确的、可靠的，并且能够适应不同的页面状态。
在操作之间，请解释你的思考过程和下一步计划。

当前平台信息：{platform_info}
当前页面信息：{page_info}
"""
    
    async def process(self, messages: List[Dict[str, str]], platform_info: Optional[Dict[str, Any]] = None, page_info: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        """
        处理用户消息
        
        Args:
            messages: 消息历史
            platform_info: 平台信息
            page_info: 页面信息
            
        Returns:
            Dict[str, Any]: 处理结果，包含回复消息和可能的工具调用
        """
        try:
            # 格式化系统提示
            formatted_system_prompt = self.system_prompt.format(
                platform_info=platform_info or "未提供平台信息",
                page_info=page_info or "未提供页面信息"
            )
            
            # 构建消息历史
            chat_messages = [SystemMessage(content=formatted_system_prompt)]
            
            # 添加历史消息
            for msg in messages:
                if msg["role"] == "user":
                    chat_messages.append(HumanMessage(content=msg["content"]))
                elif msg["role"] == "assistant":
                    chat_messages.append(AIMessage(content=msg["content"]))
            
            # 调用LLM
            logger.info("调用GenericBrowserAgent LLM")
            response = await self.llm.ainvoke(
                chat_messages,
                tools=self.tools_schema
            )
            
            # 提取工具调用
            tool_calls = self._extract_tool_calls(response.content)
            
            return {
                "message": response.content,
                "tool_calls": tool_calls
            }
        
        except Exception as e:
            logger.error(f"GenericBrowserAgent处理消息时出错: {str(e)}")
            return {
                "message": f"处理您的请求时出错: {str(e)}",
                "tool_calls": None
            }
    
    def _extract_tool_calls(self, content: str) -> Optional[List[Dict[str, Any]]]:
        """
        从回复内容中提取工具调用
        
        Args:
            content: LLM回复内容
            
        Returns:
            Optional[List[Dict[str, Any]]]: 工具调用列表，如果没有则为None
        """
        try:
            # 查找JSON代码块
            import re
            json_blocks = re.findall(r'```json\n(.*?)\n```', content, re.DOTALL)
            
            if not json_blocks:
                # 尝试查找没有语言标识的代码块
                json_blocks = re.findall(r'```\n(.*?)\n```', content, re.DOTALL)
            
            if not json_blocks:
                return None
            
            # 解析JSON
            import json
            tool_calls = []
            for block in json_blocks:
                try:
                    parsed = json.loads(block)
                    if "tool_call" in parsed:
                        tool_calls.append(parsed["tool_call"])
                except json.JSONDecodeError:
                    continue
            
            return tool_calls if tool_calls else None
        
        except Exception as e:
            logger.error(f"提取工具调用时出错: {str(e)}")
            return None 